package contact

import (
	"context"
	"git.mycaigou.com/gfyx/common/simplecopier"
	dto "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/business_opportunity"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/bigdata"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/business_opportunity"
	marketResp "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/market"
	pb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	marketPb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/market"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/gin-gonic/gin"
	"strings"
)

type contactService struct {
	contactRepo        business_opportunity.ContactRepositoryIface
	outboundCrowdRepo  marketResp.OutboundCrowdRepositoryIface
	bigDataServiceRepo bigdata.BigdataRepositoryIface
}

// NewContactService
// 创建构造函数
func NewContactService(
	contactRepo business_opportunity.ContactRepositoryIface,
	outboundCrowdRepo marketResp.OutboundCrowdRepositoryIface,
	bigDataServiceRepo bigdata.BigdataRepositoryIface,
) ContactServiceIface {
	return &contactService{
		contactRepo:        contactRepo,
		outboundCrowdRepo:  outboundCrowdRepo,
		bigDataServiceRepo: bigDataServiceRepo,
	}
}

func (s *contactService) getWinBidContact(ctx *gin.Context, request *pb.ContactListRequest, resp *pb.ContactListResponse) map[string]interface{} {
	request.Company = s.distinctName(ctx, request.Company) //中标单位去重

	res := map[string]interface{}{}
	if request.ContactType == "single_developer" {
		dataMap, err := simplecopier.StructToMapByJsonTag(resp)
		if err != nil {
			stark.Logger.Error(ctx, "struct to map,err:", err)
		}
		res["list"] = dataMap["contact_list"]
		res["total"] = resp.ContactTotal
		return res
	} else {
		cooperationCompany := &pb.ContactListResponse{}
		var companyNameArr []string
		cooperationCompanyTotal := 0
		startNum := 1
		if request.ContactType == "developer_and_supplier" {
			startNum = 0
		}
		for k, company := range request.Company {
			if company.CompanyName != "" {
				cooperationCompanyItem := &pb.CooperationCompanyList{
					CooperationCompanyName:    company.CompanyName,
					CooperationOrganizingCode: company.OrganizingCode,
				}
				//联系人列表
				contactList := make([]*pb.ContactDataList, 0)
				for _, respValue := range resp.ContactList {
					if respValue.CompanyName == company.CompanyName {
						contactList = append(contactList, respValue)
						cooperationCompanyItem.ContactCnt += 1
					}
				}
				if len(contactList) > 2 {
					cooperationCompanyItem.Contact = contactList[0:2]
				} else {
					cooperationCompanyItem.Contact = contactList
				}
				if k == 0 && request.ContactType == "developer_and_supplier" {
					cooperationCompanyItem.CompanyType = "developer"
				} else {
					cooperationCompanyItem.CompanyType = "supplier"
				}
				//联系人数量
				companyNameArr = append(companyNameArr, company.CompanyName)
				companyContactCntList := s.getCompanyTarget(ctx, companyNameArr)
				for _, cnt := range companyContactCntList {
					if company.CompanyName == cnt.DeveloperName {
						if cooperationCompanyItem.CompanyType == "developer" {
							cooperationCompanyItem.ContactCnt = cnt.PurchaseContactCnt
						} else {
							cooperationCompanyItem.ContactCnt = cnt.SupplierContactCnt
						}

					}
				}

				if cooperationCompanyTotal >= startNum {
					cooperationCompany.CooperationCompany = append(cooperationCompany.CooperationCompany, cooperationCompanyItem)
				}
				cooperationCompanyTotal += 1

			}
		}

		cooperationCompanyMap, err := simplecopier.StructToMapByJsonTag(cooperationCompany)
		if err != nil {
			stark.Logger.Error(ctx, "struct to map,err:", err)
		}
		res["list"] = cooperationCompanyMap["cooperation_company"]
		res["total"] = len(cooperationCompany.CooperationCompany)
		return res
	}

}

func (s *contactService) getCompanyTarget(ctx *gin.Context, companyName []string) []*bigdata.GetCompanyTargetItem {
	if len(companyName) <= 0 {
		return make([]*bigdata.GetCompanyTargetItem, 0)
	}
	bigdataRequest := &bigdata.GetCompanyTargetRequest{
		CompanyName: companyName,
	}
	getCompanyContactCntResponse, err := s.bigDataServiceRepo.GetCompanyTarget(ctx, bigdataRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "bigdata GetCompanyTarget,err:%s", err.Error())
	}
	return getCompanyContactCntResponse.List
}

func (s *contactService) distinctName(ctx *gin.Context, companyList []*pb.CompanyList) []*pb.CompanyList {
	newCompanyList := make([]*pb.CompanyList, 0)
	nameSet := make([]string, 0)
	for _, value := range companyList {
		item := &pb.CompanyList{}
		item.CompanyName = value.CompanyName
		item.OrganizingCode = value.OrganizingCode
		isContain := false
		for _, p := range nameSet {
			if p == value.CompanyName {
				isContain = true
			}
		}
		if !isContain {
			newCompanyList = append(newCompanyList, item)
		}
		nameSet = append(nameSet, value.CompanyName)
	}
	return newCompanyList
}

func (s *contactService) GetContactList(ctx *gin.Context, request *dto.ContactListRequest) (map[string]interface{}, error) {
	//1、构造pb请求参数
	pbRequest := &pb.ContactListRequest{
		ContactType:          request.ContactType,
		Keyword:              request.Keyword,
		PhoneType:            strings.Join(request.PhoneType, ","),
		ProvinceCode:         request.ProvinceCode,
		CityCode:             request.CityCode,
		PurchaseOwnerMobile:  request.PurchaseOwnerMobile,
		Page:                 request.Page,
		PageSize:             request.PageSize,
		CooperationTimeStart: request.CooperationTimeStart,
		CooperationTimeEnd:   request.CooperationTimeEnd,
		AreaCode:             strings.Join(request.AreaCode, ","),
		JobType:              strings.Join(request.JobType, ","),
	}
	for _, v := range request.CooperationCount {
		pbRequest.CooperationCount = append(pbRequest.CooperationCount, &pb.CooperationCount{Min: v.Min, Max: v.Max})
	}

	for _, company := range request.Company {
		pbRequest.Company = append(pbRequest.Company, &pb.CompanyList{CompanyName: company.CompanyName, OrganizingCode: company.OrganizingCode})
	}
	//2、调用rpc方法
	data, err := s.contactRepo.GetContactList(ctx, pbRequest)
	if data == nil {
		return nil, nil
	}
	if len(request.Company) == 4 { //中标特殊处理
		return s.getWinBidContact(ctx, pbRequest, data), nil
	}

	developerCount := 0
	if request.ContactType == "developer_and_supplier" && (request.Company[0].CompanyName != "" || request.Company[0].OrganizingCode != "") { //“全部” = 开发商+供应商
		developerCount += 1
		developerCompany := &pb.CooperationCompanyList{
			ContactCnt:                data.ContactTotal,
			CooperationCompanyName:    request.Company[0].CompanyName,
			CooperationOrganizingCode: request.Company[0].OrganizingCode,
			Contact:                   data.ContactList,
			CompanyType:               "developer",
		}
		if len(developerCompany.Contact) > 2 {
			developerCompany.Contact = developerCompany.Contact[0:2]
		}

		newCooperationCompany := make([]*pb.CooperationCompanyList, 0)
		newCooperationCompany = append(newCooperationCompany, developerCompany)
		for _, value := range data.CooperationCompany {
			newCooperationCompany = append(newCooperationCompany, value)
		}

		data.CooperationCompany = newCooperationCompany
	}

	res := map[string]interface{}{}
	dataMap, err := simplecopier.StructToMapByJsonTag(data)
	if err != nil {
		stark.Logger.Error(ctx, "struct to map,err:", err)
		return nil, err
	}

	switch request.ContactType {
	case "single_developer":
		res["list"] = dataMap["contact_list"]
		res["total"] = data.ContactTotal
	case "single_supplier":
		res["list"] = dataMap["contact_list"]
		res["total"] = data.ContactTotal
	case "single_customer":
		res["list"] = dataMap["contact_list"]
		res["total"] = data.ContactTotal
	case "multi_supplier":
		res["list"] = dataMap["cooperation_company"]
		res["total"] = data.CooperationCompanyTotal
	case "developer_and_supplier":
		res["list"] = dataMap["cooperation_company"]
		res["total"] = data.CooperationCompanyTotal + (int32(developerCount))
	default:
	}

	return res, nil
}

func (s *contactService) ContactDetail(ctx *gin.Context, request *pb.ContactDetailRequest) (map[string]interface{}, error) {
	contactResp, err := s.contactRepo.ContactDetail(ctx, request)
	if err != nil {
		stark.Logger.Error(ctx, "获取联系人详情，失败:", err)
		return nil, err
	}
	if len(contactResp.List) < 1 {
		return nil, nil
	}
	resp, err := simplecopier.StructToMapByJsonTag(contactResp.List[0])
	if err != nil {
		stark.Logger.Error(ctx, "struct to map，失败:", err)
	}
	return resp, nil
}

// CooperationList 合作案例
func (s *contactService) CooperationList(ctx *gin.Context, request *pb.CooperationListRequest) (map[string]interface{}, error) {
	contactResp, err := s.contactRepo.CooperationList(ctx, request)
	if err != nil {
		stark.Logger.Error(ctx, "获取合作案例，失败:", err)
		return nil, err
	}
	if contactResp.Total < 1 {
		return nil, nil
	}
	resp, err := simplecopier.StructToMapByJsonTag(contactResp)
	if err != nil {
		stark.Logger.Error(ctx, "struct to map，失败:", err)
		return nil, err
	}
	return resp, nil
}

func (s *contactService) GetMobile(ctx *gin.Context, request *pb.GetMobileRequest) (map[string]interface{}, error) {
	contactResp, err := s.contactRepo.GetMobile(ctx, request)
	if err != nil {
		stark.Logger.Error(ctx, "获取手机号，失败:", err)
		return nil, err
	}
	resp, err := simplecopier.StructToMapByJsonTag(contactResp)
	if err != nil {
		stark.Logger.Error(ctx, "struct to map，失败:", err)
		return nil, err
	}
	return resp, nil
}

// GetRpaContact 获取RPA联系人，按角色分组
func (s *contactService) GetRpaContact(ctx context.Context, request *dto.GetRpaContactRequest) (*dto.GetRpaContactResponse, error) {
	requestPb := &marketPb.GetCrowdByRpaRequest{
		ProjectId:     request.ProjectId,
		Page:          request.Page,
		PageSize:      request.PageSize,
		ShowViewTimes: true,
	}
	resPb, err := s.outboundCrowdRepo.GetCrowdByRpa(ctx, requestPb)
	res := &dto.GetRpaContactResponse{
		List: []*dto.GetRpaContact{},
	}
	if err != nil {
		stark.Logger.Errorf(ctx, "GetCrowdByRpa，err:%s", err.Error())
		return res, err
	}
	//联系人列表
	for _, v := range resPb.List {
		row := &dto.GetRpaContact{
			CompanyAddress: v.CompanyAddress,
			CompanyName:    v.CompanyName,
			Id:             v.Id,
			PersonName:     v.PersonName,
			PersonPhone:    v.PersonPhone,
			PersonPosition: v.PersonPosition,
			PersonRole:     v.PersonRole,
			PersonSexy:     v.PersonSexy,
			ProjectId:      v.ProjectId,
			RccProjectName: v.RccProjectName,
			SourceType:     v.SourceType,
			SrcId:          v.SrcId,
			ViewTimes:      v.ViewTimes,
		}
		res.List = append(res.List, row)
	}
	res.Total = resPb.Total
	return res, nil
}

// GetRpaContactGroup 获取RPA联系人，按角色分组
func (s *contactService) GetRpaContactGroup(ctx context.Context, request *dto.GetRpaContactGroupRequest) (*dto.GetRpaContactGroupResponse, error) {
	requestPb := &marketPb.GetCrowdByRpaRequest{
		ProjectId:     request.ProjectId,
		Page:          1,
		PageSize:      1000,
		ShowViewTimes: true,
	}
	resPb, err := s.outboundCrowdRepo.GetCrowdByRpa(ctx, requestPb)
	res := &dto.GetRpaContactGroupResponse{
		List: []*dto.GetRpaContactData{},
	}
	if err != nil {
		stark.Logger.Errorf(ctx, "GetCrowdByRpa，err:%s", err.Error())
		return res, err
	}
	//联系人按角色分组
	roleList := make([]*dto.GetRpaContactData, 0)
	for _, v := range resPb.List {
		roleExist := false
		for i, role := range roleList {
			if role.RoleName == v.PersonRole {
				row := &dto.GetRpaContact{
					CompanyAddress: v.CompanyAddress,
					CompanyName:    v.CompanyName,
					Id:             v.Id,
					PersonName:     v.PersonName,
					PersonPhone:    v.PersonPhone,
					PersonPosition: v.PersonPosition,
					PersonRole:     v.PersonRole,
					PersonSexy:     v.PersonSexy,
					ProjectId:      v.ProjectId,
					RccProjectName: v.RccProjectName,
					SourceType:     v.SourceType,
					SrcId:          v.SrcId,
					ViewTimes:      v.ViewTimes,
				}
				roleList[i].ContactList = append(roleList[i].ContactList, row)

				roleExist = true
			}
		}

		if roleExist == false {
			if v.PersonRole != "" { //角色名称不为空
				rowRole := &dto.GetRpaContactData{
					RoleName: v.PersonRole,
				}
				contact := &dto.GetRpaContact{
					CompanyAddress: v.CompanyAddress,
					CompanyName:    v.CompanyName,
					Id:             v.Id,
					PersonName:     v.PersonName,
					PersonPhone:    v.PersonPhone,
					PersonPosition: v.PersonPosition,
					PersonRole:     v.PersonRole,
					PersonSexy:     v.PersonSexy,
					ProjectId:      v.ProjectId,
					RccProjectName: v.RccProjectName,
					SourceType:     v.SourceType,
					SrcId:          v.SrcId,
					ViewTimes:      v.ViewTimes,
				}
				rowRole.ContactList = append(rowRole.ContactList, contact)
				roleList = append(roleList, rowRole)
			}
		}
	}

	for _, role := range roleList {
		role.ContactNum = len(role.ContactList)
	}
	res.List = roleList
	return res, nil
}

// GetRpaContactMobile 获取RPA联系人：手机号
func (s *contactService) GetRpaContactMobile(ctx context.Context, request *dto.GetRpaContactMobileRequest) (*dto.GetRpaContactMobileResponse, error) {
	requestPb := &marketPb.GetRpaContactMobileRequest{
		Id: request.Id,
	}
	resPb, err := s.outboundCrowdRepo.GetRpaContactMobile(ctx, requestPb)
	res := &dto.GetRpaContactMobileResponse{}
	if err != nil {
		stark.Logger.Errorf(ctx, "GetRpaContactMobile，err:%s", err.Error())
		return res, err
	}
	if resPb.Data == nil {
		return &dto.GetRpaContactMobileResponse{}, nil
	}
	res.Data = dto.GetRpaContact{
		CompanyAddress: resPb.Data.CompanyAddress,
		CompanyName:    resPb.Data.CompanyName,
		Id:             resPb.Data.Id,
		PersonName:     resPb.Data.PersonName,
		PersonPhone:    resPb.Data.PersonPhone,
		PersonPosition: resPb.Data.PersonPosition,
		PersonRole:     resPb.Data.PersonRole,
		PersonSexy:     resPb.Data.PersonSexy,
		ProjectId:      resPb.Data.ProjectId,
		RccProjectName: resPb.Data.RccProjectName,
		SourceType:     resPb.Data.SourceType,
		SrcId:          resPb.Data.SrcId,
		ViewTimes:      resPb.Data.ViewTimes,
	}
	return res, nil
}
